﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Lambda_表达式
{
    class Program
    {
        //参考资料https://docs.microsoft.com/zh-cn/dotnet/csharp/programming-guide/statements-expressions-operators/lambda-expressions
        delegate int del(int i);

        delegate TResult Func<TArg0, TResult>(TArg0 Arg0);

        delegate void TestDelegate(string s);


        static void Main(string[] args)
        {
            del myDelegate = x => x * x;
           
            int j = myDelegate(10);

            Console.WriteLine("delegate: " + j);

            Func<int, int> myFunc = x => x * x;

            Console.WriteLine("Func<T,R>: " + myFunc(10));

            //箭头函数
            TestDelegate testDel = n => { string str = n + " hello"; Console.WriteLine(str); };
            testDel("99");

            //普通调用
            //TestDelegate testDel = new TestDelegate(test);
            //testDel.Invoke("99");

            Func<int, bool> myFunc2 = x => x >= 9;
            Console.WriteLine("Func<TArg0,TResult>: " + myFunc2(1).ToString());

            //Lambda 表达式中的变量范围
            Test test = new Test();
            test.TestMethod(5);

            // Prove that del2 still has a copy of  
            // local variable j from TestMethod.  
            bool result = test.del2(10);

            // Output: True  
            Console.WriteLine(result);

            //数组
            int[] arr_num = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };
            int oddNumbers = arr_num.Count(n => n % 2 == 1);
            Console.WriteLine("oddNumbers: " + oddNumbers);

            var firstNumberLessthan6 = arr_num.TakeWhile(n => n < 6);
            foreach(var item in firstNumberLessthan6)
                Console.WriteLine("firstNumberLessthan6: " + item);

            var firstSmallNumbers = arr_num.TakeWhile((n, index) => n >= index);
            foreach(var item in firstSmallNumbers)
                Console.WriteLine("firstSmallNumbers: " + item.ToString());

            Console.ReadKey();
        }

        static void test(string n)
        {
            string str = n + " hello"; Console.WriteLine(str);
        }

     
    }

    delegate bool D();
    delegate bool D2(int i);


    class Test
    {

        internal D del;
        internal D2 del2;
        public void TestMethod(int input)
        {
            int j = 0;
            // Initialize the delegates with lambda expressions.  
            // Note access to 2 outer variables.  
            // del will be invoked within this method.  
            del = () => { j = 10; return j > input; };

            // del2 will be invoked after TestMethod goes out of scope.  
            del2 = (x) => { return x == j; };

            // Demonstrate value of j:  
            // Output: j = 0   
            // The delegate has not been invoked yet.  
            Console.WriteLine("j = {0}", j);        // Invoke the delegate.  
            bool boolResult = del();

            // Output: j = 10 b = True  
            Console.WriteLine("j = {0}. b = {1}", j, boolResult);
        }


    }
}
